# -*- coding: utf-8 -*-

import  wx
import  os
import  wx.wizard as wiz

#import  images
import  encodings.mbcs
import  codecs
import GenericTable
import wx.grid
import validator


import wizdata
import wizpages
from db import *
from util import *

import newcolumns

class SubclassDialog(wx.Dialog):
    def __init__(self):
        wx.Dialog.__init__(self, None, -1, 'Confirm', size=(300, 100))
        okButton = wx.Button(self, wx.ID_OK, "OK", pos=(15, 15))
        okButton.SetDefault()
        cancelButton = wx.Button(self, wx.ID_CANCEL, "Cancel",pos=(115, 15))

class MappingPage(wiz.PyWizardPage):
    def __init__(self, parent, title):
        #用户基本信息
        #收入
        #支出
        #汇总
        #self.panel = wx.Panel(self, -1)
        #wiz.WizardPageSimple.__init__(self, parent)
        wiz.PyWizardPage.__init__(self, parent)
        self.next = self.prev = None
        self.parent = parent
        
        #self.sizer = Maketitle.makePageTitle(self, title)
        self.sizer = wx.GridBagSizer(hgap=5, vgap=5)
        #wizPg.SetSizer(sizer)
        self.title = wx.StaticText(self, -1, title)
        self.title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
        self.sizer.Add(self.title, pos = (0,1),span = (1,4))        
        
        
        if __name__ == "__main__":
            print "build"
            data = wizdata.WizData()
            data.dir = 1
            self.BuildPanel()

    def __data_init(self):
        self.current = 0
        """ current active list """
        self.calist = []    #items need to be mapping
        self.colpos = {}    # column windows id --- column position
        self.poscol = {}    # selected position --- column windows id
        """ new column """
        self.newcol = []    #new columns in the database
        self.gray = []      # the unchecked item list
        self.autoset = []
        #self.checked = {}   # checked list
        #self.static = {}
        #self.btn = {}
        self.text = {}
        self.textlist = {}
        self.collist = {}
        self.mapping = {}  
        #import images
        #self.SetIcon(images.getPyIcon())

        self.column = []# self.GetData()
        
        self.textid = []
        
        cns = db.getColNames()
        items = []
        for item in cns:
            items.append( vcode(item.name) )
        #items = tuple(items)
  
        self.dbcolumns = items #.cols() #getcol.GetColumns() #self.GetData()
        
        
        
    def SetNext(self, next):
        self.next = next
      
    def SetPrev(self, prev):
        self.prev = prev
    
    def GetNext(self):
        pages = wizpages.WizPages()
        if len(self.newcol)>0:            
            pages.page5.SetPrev(pages.page4)
            return pages.page5
        else:
            pages.page6.SetPrev(pages.page4)
            return pages.page6
    
    def GetPrev(self):
        return self.prev            
            
    def ShowMap():
        print "show map"
    

    def BuildPanel(self):
        
        self.__data_init()
        
        self.i = 0
        xpos = 2
        
        st1 = wx.StaticText(self, -1, u"映射名称：", size = (120,-1))
        self.sizer.Add(st1, pos=(xpos-1,1))
        
        st2 = wx.TextCtrl(self, -1, "", size=(270, -1),validator=validator.CharValidator())
        self.sizer.Add(st2, pos=(xpos-1,2),span=(1,2))
        st2.Bind(wx.EVT_KILL_FOCUS,self.OnSetName)
        #decode("mbcs")
        #st3 = wx.StaticText(self, -1, u"分类", size = (120,-1))
        #self.sizer.Add(st3, pos=(xpos-1,3))
        cblist = (u'工资表',u'通讯录')
        cb = wx.ComboBox(self, -1, u"工资表", (90, 50), (95, -1), cblist, style = wx.CB_DROPDOWN|wx.CB_READONLY, #|wxTE_PROCESS_ENTER
                        validator=validator.CharValidator()
                        )
        self.Bind(wx.EVT_COMBOBOX, self.OnComboBox, cb)
        
        #st3 = wx.StaticText(self, -1, u"数据库列(双击）", size = (120,-1))
        self.sizer.Add(cb, pos=(xpos-1,4))
        #line = wx.StaticLine(self.parent)
        #self.sizer.Add(line, pos=(xpos+0,1),span=(1,4))

        st1 = wx.StaticText(self, -1, u"Excel 列名", size = (120,-1))
        self.sizer.Add(st1, pos=(xpos+1,1))
        
        st2 = wx.StaticText(self, -1, u"映射", size = (120,-1))
        self.sizer.Add(st2, pos=(xpos+1,2))
        
        #decode("mbcs")
        st3 = wx.StaticText(self, -1, u"列名称", size = (120,-1))
        self.sizer.Add(st3, pos=(xpos+1,3))
        self.text_map = {}
        
        #
        data = wizdata.WizData()
        data.option = 2
        if data.labels:
            self.column = data.labels
        else:
            self.column = self.GetData()
        for x in self.column:
            
            id1 = wx.NewId()
            self.colpos[id1] = self.i
            self.poscol[self.i] = id1
            cb = wx.CheckBox(self, id1, x, size = (120,-1))
            cb.SetValue(True)
            self.sizer.Add(cb, pos=(xpos+self.i+2,1))
            cb.Bind(wx.EVT_CHECKBOX, self.OnChecked)
            """
            id1 = wx.NewId()
            self.static[id1] = wx.StaticText(self, id1, x, size = (120,-1), style = wx.ALIGN_RIGHT)
            self.sizer.Add(self.static[id1], pos=(self.i+2,2))
            self.static[id1].SetBackgroundColour("white")
            """
            self.textlist[id1] = x
            #print x
            id = wx.NewId()
            
            self.mapping[id1] = id
            
            #print id
            self.text[id] = wx.TextCtrl(self, id, "", size=(100, -1),validator=validator.CharValidator())
            self.sizer.Add(self.text[id], pos=(xpos+self.i+2,2))
            self.textid.append(id)
            self.text_map[id] = x
            
            self.text[id].Bind(wx.EVT_LEFT_DCLICK,self.OnDClickText)
            self.text[id].Bind(wx.EVT_KILL_FOCUS,self.onKillFocus)
            #self.text[id].Bind(wx.EVT_LEFT_DCLICK,self.OnDClickText)            
            #self.Bind(wx.EVT_TEXT, self.OnEnterText,self.text[id])
            self.text[id].SetBackgroundColour("#FFEBCD")
            self.calist.append(id)
            self.i = self.i +1
            
        self.listBox = wx.ListBox(self, -1, size=(130, 400), choices = self.dbcolumns, style = wx.LB_SINGLE)
        
        self.sizer.Add(self.listBox, pos=(xpos+2,3),span=(self.i,1))        
        
        self.listBox.SetSelection(0) 
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, self.listBox)
        
        self.auto = wx.Button(self, -1, u"自动对应")
        self.Bind(wx.EVT_BUTTON, self.OnAuto, self.auto)
        self.sizer.Add(self.auto, pos=(xpos+2,4))

        reset = wx.Button(self, -1, u"复位")
        self.Bind(wx.EVT_BUTTON, self.OnReset, reset)
        self.sizer.Add(reset, pos=(xpos+3,4))
        
        # ############################
        
        blank = wx.StaticText(self, -1, "", size = (120,-1), style = wx.ALIGN_LEFT)
        self.sizer.Add(blank, pos=(xpos+4,4))

        some2 = wx.StaticText(self, id1, u"员工唯一标识:", size = (120,-1), style = wx.ALIGN_LEFT)
        self.sizer.Add(some2, pos=(xpos+5,4))
        
        ulist = self.GetKeyField() # (u'工号',u'身份证号码')
        ucb = wx.ComboBox(self, -1, "", (90, 50), (75, -1), ulist, style = wx.CB_DROPDOWN|wx.CB_READONLY, #|wxTE_PROCESS_ENTER
                validator=validator.ExistValidator()
                )
        self.Bind(wx.EVT_COMBOBOX, self.OnSetKey, ucb)

        self.sizer.Add(ucb, pos=(xpos+6,4))
        
        # ############################        
        
        # ############################
        blank = wx.StaticText(self, -1, "", size = (120,-1), style = wx.ALIGN_LEFT)
        self.sizer.Add(blank, pos=(xpos+7,4))

        some = wx.StaticText(self, id1, u"略去尾行数:", size = (120,-1), style = wx.ALIGN_LEFT)
        self.sizer.Add(some, pos=(xpos+8,4))
        
        vlist = ('0','1','2','3')
        vcb = wx.ComboBox(self, -1, "", (90, 50), (75, -1), vlist, style = wx.CB_DROPDOWN|wx.CB_READONLY, #|wxTE_PROCESS_ENTER
                        validator=validator.CharValidator()
                        )
        self.Bind(wx.EVT_COMBOBOX, self.OnSetLast, vcb)

        self.sizer.Add(vcb, pos=(xpos+9,4))
        # ############################
        
        some1 = wx.StaticText(self, id1, "", size = (120,-1), style = wx.ALIGN_RIGHT)
        self.sizer.Add(some1, pos=(xpos+2,5))



        #self.btn = wx.Button(self, -1, u"保存映射并导入", (480, 50))
        #self.Bind(wx.EVT_BUTTON, self.OnOK,self.btn)
        #self.statusbar = self.CreateStatusBar()
        self.SetSizer(self.sizer)
        self.Fit()
        (x, y) = self.GetSize()
        x = y = y + 100
        self.parent.SetClientSize((x,y))
        #print self.GetClientSize()
        #self.parent.Fit()
        #self.parent.FitToPage(self) # 
        
    def OnSetName(self, evt):
        data = wizdata.WizData()
        obj = evt.GetEventObject()
        data.map_name = obj.GetValue()
        
    def getMapping(self):
        mapping = []
        for id in self.textid:
            txt = self.FindWindowById(id)
            val = txt.GetValue()
            mapping.append(val)
        return mapping
        
    def changeState(id, state):
        if state == 'OnReset':
            self.autoset = []
        elif state == '':
            pass
            
    def OnSetLast(self, event):
        wd = wizdata.WizData()
        cb = event.GetEventObject()
        #data = cb.GetClientData(evt.GetSelection())
        data = event.GetSelection()
        wd.lastline = int(cb.GetValue())
        event.Skip()

    def OnSetKey(self, event):
        wd = wizdata.WizData()
        cb = event.GetEventObject()
        #data = cb.GetClientData(evt.GetSelection())
        data = event.GetSelection()
        wd.key_col = cb.GetValue() #.encode('utf8')  # unicode to utf 8
        #print "colmapping: %s" %(wd.key_col)
        event.Skip()


    def OnComboBox(self, event):
        cb = event.GetEventObject()
        #data = cb.GetClientData(evt.GetSelection())
        #maptype = event.GetSelection()
        
        data.mappingtype = cb.GetValue()
        
        event.Skip()
        


    def OnReset(self,event):
        for x in self.autoset:             # auto set should be remove when uncheck and double click
            txt = self.FindWindowById(x)
            val = txt.GetValue()
            txt.SetValue("")
            txt.SetEditable(True)
            txt.SetBackgroundColour("#FFEBCD")
            if self.dbcolumns.count(val):
                self.listBox.Append(val)
            self.calist.append(x)
        self.autoset = []
        self.calist.sort()
        self.auto.Enable(True)
        event.Skip()
    
    def OnAuto(self, event):
        index = 0
        btn_id = event.GetId()
        btn = self.FindWindowById(btn_id)
        btn.Enable(False)

        for x in self.listBox.GetStrings(): #self.sampleList:            
            for k, v in self.text_map.items():
                t = self.FindWindowById(k)
                if self.gray.count(k):
                    continue
                if x == v and self.calist.count(k):
                    self.autoset.append(k) 
                    t.SetValue(v)
                    t.SetBackgroundColour("white")
                    t.SetEditable(False)
                    self.calist.remove(k)
                    #print index, 
                    self.listBox.Delete(index)
                    index = index - 1
                else:                    
                    pass
            index = index +1
        
        self.calist.sort()
        #print self.autoset
        #print self.text_map
        
        #print self.getMapping()
        
        event.Skip()
        """
        for k, v in self.text_map.items():
            
            t = self.FindWindowById(k)
            index = 0
            for x in self.sampleList:
            
                if x == v:
                    t.SetValue(v)
                    t.SetBackgroundColour("white")
                    self.calist.remove(k)
        self.calist.sort()
        """
    
    def __setValue(self):
        pass
        
        
        
    def OnChecked(self, event):
        box_id = event.GetId()
        box = self.FindWindowById(box_id) # checkbox
        tc_id =  self.mapping[box_id]
        tc = self.FindWindowById(tc_id)
        x = tc.GetValue() # check
        if box.GetValue():
            
            self.gray.remove(tc_id)
            #print self.newcol

            self.calist.append(tc_id)
            tc.SetBackgroundColour("#FFEBCD")
            tc.SetEditable(True)
            if x == "---":
                tc.SetValue("")
            self.poscol[self.colpos[box_id]]=box_id
        else:  # uncheck
            
            if self.autoset.count(tc_id):
                self.autoset.remove(tc_id)            
            del self.poscol[self.colpos[box_id]]
            tc.SetBackgroundColour("#D3D3D3")
            
            if  self.dbcolumns.count(x) and self.newcol.count(tc_id) == 0:
                self.listBox.Append(x)
            if self.calist.count(tc_id) != 0:
                self.calist.remove(tc_id) #if set value then already removed from calist
            self.gray.append(tc_id)
            tc.SetValue("---")
            if self.newcol.count(tc_id)!=0:
                self.newcol.remove(tc_id)
                self.GetNewCol()
            #if self.newcol.count(tc_id):
            #    self.newcol.remove(tc_id)
            tc.SetEditable(False)
        self.calist.sort()
        tc.Refresh()
        event.Skip()
    def onKillFocus(self,event):
        text_id = event.GetId()
        text = self.FindWindowById(text_id)
        #print text.GetBackgroundColour()
        #text.SetBackgroundColour("#CCC000")
        #print text_id,
        str = text.GetValue()
        ct = self.listBox.FindString(str)
        #self.textState('onKillFocus')
        if self.gray.count(text_id):
            pass
        elif ct != -1:  # found in the listbox
            self.listBox.Delete(ct)
            text.SetEditable(False)
            text.SetBackgroundColour("white")
            if self.calist.count(text_id) != 0:
                self.calist.remove(text_id)
            if self.newcol.count(text_id) != 0:
                self.newcol.remove(text_id)
            # click to listbox
            
        else:    # not found in the listbox
            # todo if find it alreday in the text list then alert
            if str.strip() != "" :  # not blank
                #print str
                if text.IsModified(): # modified by someone
                    if self.findSame(str, text_id):
                        #print "str"
                        text.SetFocus()
                        self.info(text, u"出现同名项，请重新输入\n\n[单击关闭]")
                        text.SetValue("")
                    else:
                        text.SetBackgroundColour("yellow")
                        if self.newcol.count(text_id) ==0:
                            self.newcol.append(text_id)  # append to new column and remove from current active list
                            if self.calist.count(text_id) != 0:
                                self.calist.remove(text_id)
                            #self.newcol.remove(text_id)  # remove from new column list  ??? why remove here?
            else:    # the text filed is blank
                text.SetBackgroundColour("#FFEBCD")
                text.SetValue("")  # remove the space
                if self.newcol.count(text_id) != 0: # found in new column list 
                    try:
                        self.newcol.remove(text_id) # remove from new column and append to current active list
                        self.calist.append(text_id)
                    except:
                        print  "not in"
            
            self.calist.sort()
            self.Refresh()
            self.GetNewCol()
        event.Skip()
        
    def findSame(self, text, id):
        rtn = 0
        for x in self.newcol:
            if x == id:
                continue
            t = self.FindWindowById(x)
            val = t.GetValue()
            if text == val:
                rtn = 1
                break
        return rtn
    
    def GetKeyField(self):
        sql = "select name from aid_columns where table_='aid_employees' and keycol = 1"
        
        result_set = db.execute(sql)
        rtn = []
        for row in result_set:
            rtn.append(vcode(row.name))
        return tuple(rtn)
        
        
    def GetNewCol(self):
        data = wizdata.WizData()
        newcol = []
        #data.newcol = []
        for x in self.newcol:
            #print x,
            t = self.FindWindowById(x)
            val = t.GetValue()
            newcol.append(val)
        #print newcol
        #print
        data.newcol = newcol
        #print data.newcol

        #print "-------------------"

    def Process(self):
        progressMax = 100
        dialog = wx.ProgressDialog("Saving...", "Time remaining", progressMax, style=wx.PD_CAN_ABORT | wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)
        keepGoing = True
        count = 0
        while keepGoing and count < progressMax:
            count = count + 1
            wx.Sleep(1)
            keepGoing = dialog.Update(count)
        dialog.Destroy()

    def GetData(self):
        """
        sampleList = ['zero', 'one', 'two', 'three', 'four', 'five',
                      'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
                      'twelve', 'thirteen', 'fourteen']
        """
        sampleList = [u'序号',u'员工编号',u'姓名',u'部门',u'标准工资',u'浮动工资',
                      u'计时工资',u'计件工资',u'水电补贴',u'职务补贴',u'误餐补贴',
                      u'应发工资',u'病假扣款',u'待业金',u'养老金',u'公积金',u'所得税',u'实发工资']
        #print sampleList
        
        i = 0
        """
        for x in sampleList:
            sampleList[i] = x.decode("mbcs")
            #print sampleList[i]
            i = i+1
        """
        """
        self.dict0 = dict()
        i = 0
        for x in sampleList:
            self.dict0[x] = i
            i = i +1
        """
        #for x in self.dict0:
        #    print x,self.dict0[x]
        #self.mydict
        return sampleList

    def GetCA(self):
        #get the first one
        return self.calist.pop(0)
        
    def OnDClickText(self, event):
        #self.button.SetLabel("Over Me!")
        text_id = event.GetId()
        if self.gray.count(text_id):
            pass
        else:
            text = self.FindWindowById(text_id)
            text.SetBackgroundColour("#FFEBCD")
            x =  text.GetValue()
            if self.autoset.count(text_id):
                self.autoset.remove(text_id) 
            text.SetValue("")
            text.SetEditable(True)
            if self.newcol.count(text_id) == 0:  # not in the new column list
                if x != "" and self.calist.count(text_id)==0:
                    self.listBox.Append(x)
            else:  # in the new column list
                self.newcol.remove(text_id)
                self.calist.append(text_id)
            if self.calist.count(text_id) ==0:  # not in the current active list
                self.calist.append(text_id)
            self.calist.sort()
            #self.statusbar.SetStatusText("removed")
            #self.calist.reverse()
        event.Skip()
    def EvtListBoxDClick(self, event):
        #for x in self.text:
        #    print x.getValue()
        lb = event.GetEventObject()
        if len(self.calist) == 0:
            #self.statusbar.SetStatusText("no space")
            pass
            self.info(lb, u"任务已完成")
        else:
            ct = self.GetCA()
            self.text[ct].SetValue(self.listBox.GetStringSelection())
            self.listBox.Delete(self.listBox.GetSelection())
            self.text[ct].SetEditable(False)
            self.text[ct].SetBackgroundColour("white")
            #self.statusbar.SetStatusText("added")
        event.Skip()
        
    def info(self, obj, info):        
        win = InfoPopup(self, info, wx.SIMPLE_BORDER)
        pos = obj.ClientToScreen( (0,0) )
        sz =  obj.GetSize()
        win.Position(pos, (0, sz[0]))
        win.Show(True)
class InfoPopup(wx.PopupWindow):
    """Adds a bit of text and mouse movement to the wx.PopupWindow"""
    
   
    def __init__(self, parent, info, style):
        self.infotext = info
        wx.PopupWindow.__init__(self, parent, style)
        self.SetBackgroundColour("white")
        st = wx.StaticText(self, -1, info, pos=(10,10))
        sz = st.GetBestSize()
        self.SetSize( (sz.width+20, sz.height+20) )
        self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
        self.Bind(wx.EVT_MOTION, self.OnMouseMotion)
        self.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
        self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
        st.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
        st.Bind(wx.EVT_MOTION, self.OnMouseMotion)
        st.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
        st.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)

        wx.CallAfter(self.Refresh)


    def OnMouseLeftDown(self, evt):
        self.Refresh()
        self.ldPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
        self.wPos = self.ClientToScreen((0,0))
        self.CaptureMouse()

    def OnMouseMotion(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            dPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
            nPos = (self.wPos.x + (dPos.x - self.ldPos.x),
                    self.wPos.y + (dPos.y - self.ldPos.y))
            self.Move(nPos)

    def OnMouseLeftUp(self, evt):
        self.Show(False)
        self.Destroy()        
        #self.ReleaseMouse()

    def OnRightUp(self, evt):
        self.Show(False)
        self.Destroy()        
        
class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "", size=(800, 660)) 
        wizard = wiz.Wizard(self, -1, u"向导",style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
        page1 = MappingPage(wizard, u"建立映射关系")
        page2 = newcolumns.NewColumnsPage(wizard, u"建立关系")
        
        page1.SetNext(page2)
        page2.SetPrev(page1)
        
        wizard.FitToPage(page1)
        wizard.RunWizard(page1)

def test():
    app = wx.PySimpleApp()
    TestFrame().Show()
    app.MainLoop() 


if __name__ == "__main__":
    test()
